package com.bckj.fastboot.flow.process;

import com.bckj.fastboot.core.lang.exception.BusinessException;
import com.bckj.fastboot.flow.model.BpmnProcess;
import com.bckj.fastboot.flow.model.FastProcess;
import com.bckj.fastboot.flow.repository.FastProcessRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@RequiredArgsConstructor
public class BpmnProcessProvider {

    private final FastProcessRepository fastProcessRepository;
    private static final Map<String, BpmnProcess> PROCESS_MAP = new ConcurrentHashMap<>();

    public BpmnProcess getProcess(String processId) {
        Integer version = getFastProcessVersion(processId);
        // 使用 computeIfAbsent 保证线程安全
        return PROCESS_MAP.compute(processId, (key, existingProcess) -> {
            if (isAvailable(existingProcess, version)) {
                return existingProcess;
            }
            FastProcess fastProcess = getFastProcess(processId);
            return createProcess(fastProcess);
        });
    }

    private FastProcess getFastProcess(String processId) {
        return this.fastProcessRepository.getByProcessId(processId);
    }

    private Integer getFastProcessVersion(String processId) {
        return this.fastProcessRepository.getVersionByProcessId(processId);
    }

    private boolean isAvailable(BpmnProcess process, Integer version) {
        return process != null && process.getVersion() >= version;
    }

    private BpmnProcess createProcess(FastProcess fastProcess) {
        try {
            BpmnProcess process = BpmnProcessParser.parseBpmn(fastProcess.getContent());
            process.execute(new BpmnSetupVisitor(process));
            process.setVersion(fastProcess.getVersion());
            return process;
        } catch (Exception e) {
            log.error("解析BPMN流程失败，processId={}", fastProcess.getProcessId(), e);
            throw new BusinessException("解析BPMN流程失败，processId=" + fastProcess.getProcessId());
        }
    }
}
